#ifndef __UDSF_SYS_API_C_
#define __UDSF_SYS_API_C_

#include "sdk_ifs_udk_cfg.h"

/*
*   notice:
*   UDSF 同UDF编程：不可调用cstd-lib,只可调用"sdk_ifs_udk_cfg.h"、"sys_api.h"中列出的API函数。
*   UDSF文件内函数均需使用static修饰符，且UDF中以#include "UDSF.c"形式引用

本函数复刻 radar.lib 中 部分函数（应用中要求执行时间短）
*/

static void udsf_udkv2_init(void) __attribute__((unused));
static void udsf_udkv2_init(void){
	if( *p_sdk_version <= SDK_VERSION_GENE(0,2) ){ // 老rom
		p_gb_sysboot->boot_flag = 0;
		p_gb_sysboot->udt_src = UDT_SRC_OUTER;
	}
}
	
static void udsf_prepdata_handle(void) __attribute__((unused));
static void udsf_copy_handle(COPY_CONFIG *sCopy,uint32_t sSrcOffset,uint32_t sDstOffset) __attribute__((unused));
static void udsf_copywin_handle(uint16_t *srcAddr,WIN_CFG *sCfg) __attribute__((unused));
static uint32_t udsf_cfar_handle(CFAR_CONFIG *sCfg) __attribute__((unused));
static void udsf_angle_seq_pre(PARAM_DATAPREP *sCfg) __attribute__((unused));
static void udsf_fft3d_pre_handle(FFT3D_PRE *sCfg,STRUCT_POINTRST *sRst) __attribute__((unused));
static void udsf_bbe_waitisr(uint32_t val) __attribute__((unused));
static void udsf_rf_venus_deinit(void) __attribute__((unused));
static void udsf_p2_fft_handle(P2_FFT_CONFIG *sCfg) __attribute__((unused));
static void udsf_p2_fft_stepcfg8_handle(P2_FFT_CONFIG *sCfg,uint32_t Step) __attribute__((unused));
static void udsf_bbe_prepinit(PARAM_DATAPREP *sCfg) __attribute__((unused));
static void udsf_rf_venus_init(void) __attribute__((unused));
static void udsf_anacfg_set(ANACFG *sCfg) __attribute__((unused));
static void udsf_wdt_rstnow(void) __attribute__((unused));
static void udsf_cmphit_cfar_target(uint16_t aLen,BBE_CFARRST_T *aArray,uint16_t bLen,BBE_CFARRST_T *bArray,_Bool *hitAFlag,_Bool *hitBFlag) __attribute__((unused));

extern const uint16_t SDATA_winRange[MAX_WIN_RANGE];
extern const uint16_t SDATA_winVel[MAX_WIN_VEL];
extern const int SDATA_afftArrayPre[NUM_ANGLE*2];

void udsf_prepdata_handle(void){
		/*angleseq pre*/
	if(paramDataPrep->constEn&CONST_ANGLE_EN){
		udsf_angle_seq_pre(paramDataPrep);
	} 
	if(paramDataPrep->constEn&CONST_WINRANGE_EN){
		udsf_copywin_handle((uint16_t *)&SDATA_winRange[0],&paramDataPrep->winRange);
	}
	if(paramDataPrep->constEn&CONST_WINVEL_EN){
		udsf_copywin_handle((uint16_t *)&SDATA_winVel[0],&paramDataPrep->winVel);
	}
	/*copy1-3*/
	if(paramALG->copyEn&COPY1_EN)    {
		udsf_copy_handle(&paramALG->copy1,0,0);		
	}
	if(paramALG->copyEn&COPY2_EN)    {
		udsf_copy_handle(&paramALG->copy2,0,0);
	}
	if(paramALG->copyEn&COPY3_EN)    {
		udsf_copy_handle(&paramALG->copy3,0,0);			
	}
}

void udsf_copy_handle(COPY_CONFIG *sCopy,uint32_t sSrcOffset,uint32_t sDstOffset){
	
	uint8_t  *srcBuf  =(uint8_t  *)(sCopy->srcAddr+sSrcOffset);	
	uint8_t  *dstBuf  =(uint8_t  *)(sCopy->dstAddr+sDstOffset);
	
	switch(sCopy->mode){
		case 0: //8bit
			for(uint32_t i=0;i<sCopy->len;i++){
				*(uint8_t *)dstBuf=*(uint8_t *)srcBuf;
				dstBuf+=sCopy->dstInc;
				srcBuf+=sCopy->srcInc;
			}
			break;
		case 1://16bit
			for(uint32_t i=0;i<sCopy->len;i++){
				*(uint16_t *)dstBuf=*(uint16_t *)srcBuf;
				dstBuf+=sCopy->dstInc;
				srcBuf+=sCopy->srcInc;
			}
			break;
		case 2: //32bit
			for(uint32_t i=0;i<sCopy->len;i++){
				*(uint32_t *)dstBuf=*(uint32_t *)srcBuf;
				dstBuf+=sCopy->dstInc;
				srcBuf+=sCopy->srcInc;
			}
			break;
	}
}

void udsf_copywin_handle(uint16_t *srcAddr,WIN_CFG *sCfg){
	uint8_t *dstBuf=(uint8_t *)(0x30000000+sCfg->dstOffsetAddr);
	uint8_t *srcBuf=(uint8_t *)srcAddr;
	for(uint32_t i=0;i<sCfg->len;i++){
			*(uint16_t *)dstBuf=*(uint16_t *)srcBuf;
			dstBuf+=sCfg->dstInc;
			srcBuf+=sCfg->srcInc;		
	}
}

uint32_t udsf_cfar_handle(CFAR_CONFIG *sCfg){
	uint32_t rtn;
	bbe_regb_str->CFAR_CFG0=sCfg->cfarCfg0;
	bbe_regb_str->CFAR_CFG1=sCfg->cfarCfg1;
	bbe_regb_str->CFAR_CFG2=sCfg->cfarCfg2;
	bbe_regb_str->CFAR_CFG3=sCfg->cfarCfg3;
	bbe_regb_str->CFAR_CFG4=sCfg->cfarCfg4;
	bbe_regb_str->CFAR_CFG5=sCfg->cfarCfg5;
	bbe_regb_str->CFAR_CFG6=sCfg->cfarCfg6;
	bbe_regb_str->CFAR_CFG7=sCfg->cfarCfg7;
	bbe_regb_str->CFAR_CFG8=sCfg->cfarCfg8;	
	BBE_ISR_CLEAR(BBE_ISR_CFAR_END);
	BBE_OPGATE_EN(BBE_GATE_CFAR);
	BBE_OPTRIG(BBE_TRIG_CFAR);
	udsf_bbe_waitisr(BBE_ISR_CFAR_END);
	BBE_OPGATE_DIS(BBE_GATE_CFAR);
	rtn = bbe_regb_str->CFAR_STA0;
	return rtn;
}

void udsf_angle_seq_pre(PARAM_DATAPREP *sCfg){
	int32_t *src0Addr=(int32_t *)(BBE_ABUF0_CMPLX_BASE); //seq
	int32_t *src1Addr=(int32_t *)(BBE_ABUF1_CMPLX_BASE); //ap
	for(uint32_t i=0;i<NUM_ANGLE;i++){
		src0Addr[i*4]=8192; //8192=1
		src0Addr[i*4+1]=0;
		src0Addr[i*4+2]=SDATA_afftArrayPre[i*2];
		src0Addr[i*4+3]=SDATA_afftArrayPre[i*2+1];
	}
	src1Addr[0]=8192; //8192=1
	src1Addr[1]=0;
	src1Addr[2]=sCfg->calibAnt2_r;
	src1Addr[3]=sCfg->calibAnt2_i;	//-8096,-3755
	BBE_P2_CFG0(ANT_MAX_NUM-1,P2_FIX2PF_LSFB_0BIT,P2_MAX_CLR_EN,P2_FFT_MODE_DIS,P2_DMA_DSIZE_32BIT,P2_RSF_DIV1,P2_SUBMODE_0,P2_MODE_MUL); //intraCnt,p2_fft_mode,dma_dsize,rsfBit,sub_mode,mode
	BBE_P2_CFG1(0,NUM_ANGLE-1);//jumpCnt,interCnt
	BBE_P2_CFG2(0,0);//ncoMode,nco_fcw
	BBE_P2_CFG3(0,NUM_BYTE32*ANT_MAX_NUM);//src0JumpInc,src0InterInc
	BBE_P2_CFG4(NUM_BYTE32,BBE_ABUF0_OFFSET);//src0IntraInc,src0BaseAddr
	BBE_P2_CFG5(0,0);//src1JumpInc,src1InterInc
	BBE_P2_CFG6(NUM_BYTE32,BBE_ABUF1_OFFSET);//src1IntraInc,src1BaseAddr
	BBE_P2_CFG7(0,NUM_BYTE32*ANT_MAX_NUM);//dstJumpInc,dstInterInc
	BBE_P2_CFG8(NUM_BYTE32,sCfg->angleDstAddr);//dstIntraInc,dstBaseAddr		
	
	BBE_ISR_CLEAR(BBE_ISR_P2_JUMP_END);
	BBE_OPGATE_EN(BBE_GATE_P2);
	BBE_OPTRIG(BBE_TRIG_P2);	
	udsf_bbe_waitisr(BBE_ISR_P2_JUMP_END);
}

void udsf_fft3d_pre_handle(FFT3D_PRE *sCfg,STRUCT_POINTRST *sRst){
	uint32_t *inBuf=(uint32_t *)(sCfg->srcAddr);
	uint32_t *outBuf=(uint32_t *)(sCfg->dstAddr);
	for(uint32_t cnt=0;cnt<sRst->targetNum;cnt++){
		outBuf[cnt*2]=inBuf[sRst->target[cnt].d2Idx*sCfg->interCnt+sRst->target[cnt].d1Idx*sCfg->intraCnt];
	}
}



void udsf_bbe_waitisr(uint32_t val){
   while( (bbe_regb_str->ISR & val)==0 );
		bbe_regb_str->ISR = val;	
}

void udsf_rf_venus_deinit(void){
	ana_Venus_st->ramp_cmd=VENUS_WAVE_STOP;
}

void udsf_p2_fft_handle(P2_FFT_CONFIG *sCfg){
	bbe_regb_str->P2_CFG0=sCfg->p2Cfg0;
	bbe_regb_str->P2_CFG1=sCfg->p2Cfg1;
	bbe_regb_str->P2_CFG2=sCfg->p2Cfg2;
	bbe_regb_str->P2_CFG3=sCfg->p2Cfg3;
	bbe_regb_str->P2_CFG4=sCfg->p2Cfg4;
	bbe_regb_str->P2_CFG5=sCfg->p2Cfg5;
	bbe_regb_str->P2_CFG6=sCfg->p2Cfg6;
	bbe_regb_str->P2_CFG7=sCfg->p2Cfg7;
	bbe_regb_str->P2_CFG8=sCfg->p2Cfg8;
	BBE_ISR_CLEAR(BBE_ISR_P2_JUMP_END|BBE_ISR_FFT_UNLOAD_END);
	if((bbe_regb_str->P2_CFG0>>BB_BIT14_POS)&P2_FFT_MODE_EN){
		bbe_regb_str->FFT_CFG0=sCfg->fftCfg0;
		bbe_regb_str->FFT_CFG1=sCfg->fftCfg1;
		bbe_regb_str->FFT_CFG2=sCfg->fftCfg2;		
		BBE_OPGATE_EN(BBE_GATE_P2|BBE_GATE_FFT);
	}else{
		BBE_OPGATE_EN(BBE_GATE_P2);
	}
	BBE_OPTRIG(BBE_TRIG_P2);
	udsf_bbe_waitisr(BBE_ISR_P2_JUMP_END);
	BBE_OPGATE_DIS(BBE_GATE_P2|BBE_GATE_FFT);	
}

void udsf_p2_fft_stepcfg8_handle(P2_FFT_CONFIG *sCfg,uint32_t Step){
	bbe_regb_str->P2_CFG0=sCfg->p2Cfg0;
	bbe_regb_str->P2_CFG1=sCfg->p2Cfg1;
	bbe_regb_str->P2_CFG2=sCfg->p2Cfg2;
	bbe_regb_str->P2_CFG3=sCfg->p2Cfg3;
	bbe_regb_str->P2_CFG4=sCfg->p2Cfg4;
	bbe_regb_str->P2_CFG5=sCfg->p2Cfg5;
	bbe_regb_str->P2_CFG6=sCfg->p2Cfg6;
	bbe_regb_str->P2_CFG7=sCfg->p2Cfg7;
	bbe_regb_str->P2_CFG8=sCfg->p2Cfg8+Step;
	BBE_ISR_CLEAR(BBE_ISR_P2_JUMP_END|BBE_ISR_FFT_UNLOAD_END);
	if((bbe_regb_str->P2_CFG0>>BB_BIT14_POS)&P2_FFT_MODE_EN){
		bbe_regb_str->FFT_CFG0=sCfg->fftCfg0;
		bbe_regb_str->FFT_CFG1=sCfg->fftCfg1;
		bbe_regb_str->FFT_CFG2=sCfg->fftCfg2;		
		BBE_OPGATE_EN(BBE_GATE_P2|BBE_GATE_FFT);
	}else{
		BBE_OPGATE_EN(BBE_GATE_P2);
	}
	BBE_OPTRIG(BBE_TRIG_P2);
	udsf_bbe_waitisr(BBE_ISR_P2_JUMP_END);
	BBE_OPGATE_DIS(BBE_GATE_P2|BBE_GATE_FFT);	
}

void udsf_bbe_prepinit(PARAM_DATAPREP *sCfg){
	BBE_OPGATE_DIS(BBE_GATE_PREP);
	BBE_OPCLEAR(BBE_CLEAR_PREP);		
	BBE_ISR_CLEAR(BBE_ISR_RAMP_PEDGE|BBE_ISR_PREP_FRAME_END|BBE_ISR_PREP_RAMP_END);
	bbe_regb_str->PREP_CFG0=sCfg->prepCfg0;
	bbe_regb_str->PREP_CFG1=sCfg->prepCfg1;
	bbe_regb_str->PREP_CFG2=sCfg->prepCfg2;	
	BBE_OPGATE_EN(BBE_GATE_PREP);
}

void udsf_rf_venus_init(void){
	ana_Venus_st->ramp_pll_cfg=paramANA_Venus->ramp_pll_cfg;
	ana_Venus_st->ramp_syncw_cfg=paramANA_Venus->ramp_syncw_cfg;
	ana_Venus_st->ramp_chirpw_cfg=paramANA_Venus->ramp_chirpw_cfg;
	ana_Venus_st->ramp_wm_cfg0=paramANA_Venus->ramp_wm_cfg0;
	ana_Venus_st->ramp_mem03=paramANA_Venus->ramp_mem03;
	ana_Venus_st->ramp_mem02=paramANA_Venus->ramp_mem02;
	ana_Venus_st->ramp_mem01=paramANA_Venus->ramp_mem01;
	ana_Venus_st->ramp_mem00=paramANA_Venus->ramp_mem00;
	ana_Venus_st->ramp_mem13=paramANA_Venus->ramp_mem13;
	ana_Venus_st->ramp_mem12=paramANA_Venus->ramp_mem12;
	ana_Venus_st->ramp_mem11=paramANA_Venus->ramp_mem11;
	ana_Venus_st->ramp_mem10=paramANA_Venus->ramp_mem10;
}

void udsf_anacfg_set(ANACFG *sCfg){
	ana_Venus_st->ana_cfg0=sCfg->ana_cfg0;
	ana_Venus_st->ana_cfg1=sCfg->ana_cfg1;
	ana_Venus_st->ana_cfg2=sCfg->ana_cfg2;
}

void udsf_wdt_rstnow(void){
	SYSC->CLK_EN |= WDT_PATTERN_EN_Msk;
	WDT->CMP = 0;	
	WDT->STR = 0x1;
}

void udsf_cmphit_cfar_target(uint16_t aLen,BBE_CFARRST_T *aArray,uint16_t bLen,BBE_CFARRST_T *bArray,_Bool *hitAFlag,_Bool *hitBFlag){
	
	for( int i=0;i<CFAR_MAX_NUM;i++ ){
		hitAFlag[i] = 0;
		hitBFlag[i] = 0;
	}
	
	for(uint32_t i=0;i<aLen;i++){
		for(uint32_t j=0;j<bLen;j++){
			if(!hitBFlag[j]){
				if((aArray[i].interIdx == bArray[j].intraIdx)&&(aArray[i].intraIdx == bArray[j].interIdx)){
					hitAFlag[i]=1;
					hitBFlag[j]=1;
				}
			}
		}
	}
}


#endif
